package com.jiantong.work.impl.manager;

import com.google.common.collect.Maps;
import com.jiantong.common.util.UserUtil;
import com.jiantong.user.ext.LoginUser;
import com.jiantong.work.dto.RetailImmunizationRecordDto;
import com.jiantong.work.enums.AnimalMarkStatus;
import com.jiantong.work.enums.DocumentsDeleteFlag;
import com.jiantong.work.enums.DocumentsType;
import com.jiantong.work.impl.dao.AnimalMarkDao;
import com.jiantong.work.impl.dao.ReportHandleResumeDao;
import com.jiantong.work.impl.dao.RetailImmunizationRecordDao;
import com.jiantong.work.impl.dao.RetailImmunizationSubRecordDao;
import com.jiantong.work.model.ReportHandleResume;
import com.jiantong.work.model.RetailImmunizationRecord;
import com.jiantong.work.model.RetailImmunizationSubRecord;
import com.jiantong.work.util.Utils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by mz on 19/9/17.
 *
 */
@Component
public class RetailImmunizationRecordManager {

    private final ReportHandleResumeDao reportHandleResumeDao;

    private final RetailImmunizationRecordDao retailImmunizationRecordDao;

    private final RetailImmunizationSubRecordDao retailImmunizationSubRecordDao;

    private final AnimalMarkDao animalMarkDao;

    @Autowired
    public RetailImmunizationRecordManager(RetailImmunizationRecordDao retailImmunizationRecordDao,
                                           RetailImmunizationSubRecordDao retailImmunizationSubRecordDao,
                                           ReportHandleResumeDao reportHandleResumeDao,
                                           AnimalMarkDao animalMarkDao) {
        this.retailImmunizationRecordDao = retailImmunizationRecordDao;
        this.retailImmunizationSubRecordDao = retailImmunizationSubRecordDao;
        this.reportHandleResumeDao = reportHandleResumeDao;
        this.animalMarkDao = animalMarkDao;
    }

    @Transactional
    public Long create(RetailImmunizationRecordDto retailImmunizationRecordDto , Integer toStatus){

        RetailImmunizationRecord retailImmunizationRecord = retailImmunizationRecordDto.getRetailImmunizationRecord();
        List<Map<String , Object>> vaccines = retailImmunizationRecordDto.getVaccines();
        Integer fromStatus = retailImmunizationRecord.getStatus();

        LoginUser loginUser = UserUtil.getCurrentUser();
        String prefix = "RFY";
        prefix = Utils.createPrefix(prefix,loginUser);//单据编号前缀的开头字母 和 当前用户
        String number = Utils.create(prefix,retailImmunizationRecordDao.findCurrentMaxNumber(prefix));//要在表中拿到当前最大的Number号
        retailImmunizationRecord.setNumber(number);

        retailImmunizationRecord.setDeleteFlag(DocumentsDeleteFlag.NORMAL.value());

        if(toStatus != null && !fromStatus.equals(toStatus)){
            retailImmunizationRecord.setStatus(toStatus);
            retailImmunizationRecordDao.create(retailImmunizationRecord);

            ReportHandleResume reportHandleResume = new ReportHandleResume();

            reportHandleResume.setReportId(retailImmunizationRecord.getId());
            reportHandleResume.setReportNumber(retailImmunizationRecord.getNumber());
            reportHandleResume.setType(DocumentsType.RETAIL_IMMUNIZATION_RECORD.value());
            reportHandleResume.setFromStatus(fromStatus);
            reportHandleResume.setToStatus(toStatus);
            reportHandleResume.setUserId(loginUser.getId());
            reportHandleResume.setUserName(loginUser.getName());
            reportHandleResumeDao.create(reportHandleResume);
        }else {
            retailImmunizationRecordDao.create(retailImmunizationRecord);
        }

        if(vaccines != null && !vaccines.isEmpty()){
            List<RetailImmunizationSubRecord> retailImmunizationSubRecords = buildRetailImmunizationSubRecord(vaccines,retailImmunizationRecord.getId());
            if(!retailImmunizationSubRecords.isEmpty()){
                retailImmunizationSubRecordDao.creates(retailImmunizationSubRecords);
            }
        }

        List<String> currentMarkNumbers = retailImmunizationRecord.getEarNumbers();
        if(currentMarkNumbers != null && !currentMarkNumbers.isEmpty()){
            Map<String , Object> map1 = Maps.newHashMap();
            map1.put("markNumbers",currentMarkNumbers);
            map1.put("status", AnimalMarkStatus.USE.value());
            map1.put("woreAt",new Date());
            animalMarkDao.updateMarks(map1);
        }
        return retailImmunizationRecord.getId();
    }


    @Transactional
    public Boolean update(RetailImmunizationRecordDto retailImmunizationRecordDto , Integer toStatus){
        RetailImmunizationRecord retailImmunizationRecord = retailImmunizationRecordDto.getRetailImmunizationRecord();
        List<Map<String , Object>> vaccines = retailImmunizationRecordDto.getVaccines();
        List<String> originalEar = retailImmunizationRecordDto.getOriginalEar();
        List<String> currentEar = retailImmunizationRecord.getEarNumbers();
        Integer fromStatus = retailImmunizationRecord.getStatus();

        LoginUser loginUser = UserUtil.getCurrentUser();

        if (toStatus != null && !fromStatus.equals(toStatus)){
            retailImmunizationRecord.setStatus(toStatus);
            retailImmunizationRecordDao.update(retailImmunizationRecord);

            ReportHandleResume reportHandleResume = new ReportHandleResume();

            reportHandleResume.setReportId(retailImmunizationRecord.getId());
            reportHandleResume.setReportNumber(retailImmunizationRecord.getNumber());
            reportHandleResume.setType(DocumentsType.RETAIL_IMMUNIZATION_RECORD.value());
            reportHandleResume.setFromStatus(fromStatus);
            reportHandleResume.setToStatus(toStatus);
            reportHandleResume.setUserId(loginUser.getId());
            reportHandleResume.setUserName(loginUser.getName());
            reportHandleResumeDao.create(reportHandleResume);

        }else {
            retailImmunizationRecordDao.update(retailImmunizationRecord);
        }

        if(vaccines != null && !vaccines.isEmpty()){
            updateRetailImmunizationSubRecord(vaccines,retailImmunizationRecord.getId());
            List<RetailImmunizationSubRecord> retailImmunizationSubRecords = buildRetailImmunizationSubRecord(vaccines,retailImmunizationRecord.getId());
            if(!retailImmunizationSubRecords.isEmpty()){
                retailImmunizationSubRecordDao.creates(retailImmunizationSubRecords);
            }
        }

        if(originalEar != null && !originalEar.isEmpty()){
            Map<String , Object> map1 = Maps.newHashMap();
            map1.put("markNumbers",originalEar);
            map1.put("status", AnimalMarkStatus.DEPOSITED.value());
            map1.put("woreAt",null);
            animalMarkDao.updateMarks(map1);
        }

        if(currentEar != null && !currentEar.isEmpty()){
            Map<String , Object> map1 = Maps.newHashMap();
            map1.put("markNumbers",currentEar);
            map1.put("breedStableId",null);
            map1.put("breedStableNumber",null);
            map1.put("status", AnimalMarkStatus.USE.value());
            map1.put("woreAt",retailImmunizationRecord.getCreatedAt());
            animalMarkDao.updateMarks(map1);
        }

        return Boolean.TRUE;
    }


    private List<RetailImmunizationSubRecord> buildRetailImmunizationSubRecord(List<Map<String, Object>> vaccines, Long id) {

        List<RetailImmunizationSubRecord> list = new ArrayList<>();
        RetailImmunizationSubRecord retailImmunizationSubRecord = null;

        for(Map<String , Object> map : vaccines){
            if(map.getOrDefault("id",null)== null){
                retailImmunizationSubRecord = new RetailImmunizationSubRecord();

                retailImmunizationSubRecord.setVaccineId(id);
                retailImmunizationSubRecord.setBreedSecondType((Integer) map.getOrDefault("breedSecondType",null));
                retailImmunizationSubRecord.setVaccineType((Integer) map.getOrDefault("vaccineType",null));
                retailImmunizationSubRecord.setOtherType((String) map.getOrDefault("otherType",null));
                retailImmunizationSubRecord.setVaccineCode((Integer) map.getOrDefault("vaccineCode",null));
                retailImmunizationSubRecord.setVaccineName((String) map.getOrDefault("vaccineName",null));

                Object object = map.getOrDefault("date",new Date());
                Date date = null;
                if(object instanceof Long) date = new Date((long)object);
                else if(object instanceof String) date = DateTime.parse((String)object).toDate();
                else if(object instanceof char[]) date = DateTime.parse((String)object).toDate();

                retailImmunizationSubRecord.setDate(date);
                retailImmunizationSubRecord.setDays((Integer) map.getOrDefault("days",null));
                retailImmunizationSubRecord.setTimes((Integer) map.getOrDefault("times",null));
                retailImmunizationSubRecord.setQuantity((Integer) map.getOrDefault("quantity",null));

                Object dq = map.getOrDefault("drugQuantity",null);
                Double drugQuantity = 0.00;
                if(dq instanceof Integer) drugQuantity = ((Integer)dq).doubleValue();

                if(dq instanceof Float) drugQuantity = ((Float) dq).doubleValue();

                if(dq instanceof Long) drugQuantity = ((Long) dq).doubleValue();

                if(dq == null) drugQuantity = 0.00;

                retailImmunizationSubRecord.setDrugQuantity(drugQuantity);
                retailImmunizationSubRecord.setMethod((Integer) map.getOrDefault("method",null));
                retailImmunizationSubRecord.setDrugUnit((Integer) map.getOrDefault("drugUnit",null));
                retailImmunizationSubRecord.setManufacturerJson((String) map.getOrDefault("manufacturerJson",null));
                retailImmunizationSubRecord.setBatchJson((String) map.getOrDefault("batchJson",null));
                retailImmunizationSubRecord.setOperatorName((String) map.getOrDefault("operatorName",null));
                retailImmunizationSubRecord.setDeleteFlag(DocumentsDeleteFlag.NORMAL.value());

                list.add(retailImmunizationSubRecord);
            }
        }

        return list;
    }


    private void updateRetailImmunizationSubRecord(List<Map<String, Object>> vaccines,Long vaccineId) {

        RetailImmunizationSubRecord retailImmunizationSubRecord = null;

        for(Map<String , Object> map : vaccines) {
            if (map.getOrDefault("id", null) != null) {
                retailImmunizationSubRecord = new RetailImmunizationSubRecord();
                retailImmunizationSubRecord.setId(((Integer) map.get("id")).longValue());
                retailImmunizationSubRecord.setVaccineId(vaccineId);
                retailImmunizationSubRecord.setBreedSecondType((Integer) map.getOrDefault("breedSecondType", null));
                retailImmunizationSubRecord.setVaccineType((Integer) map.getOrDefault("vaccineType", null));
                retailImmunizationSubRecord.setOtherType((String) map.getOrDefault("otherType", null));
                retailImmunizationSubRecord.setVaccineCode((Integer) map.getOrDefault("vaccineCode", null));
                retailImmunizationSubRecord.setVaccineName((String) map.getOrDefault("vaccineName", null));

                Object object = map.getOrDefault("date", new Date());
                Date date = null;
                if (object instanceof Long) date = new Date((long) object);
                else if (object instanceof String) date = DateTime.parse((String) object).toDate();
                else if (object instanceof char[]) date = DateTime.parse((String) object).toDate();

                retailImmunizationSubRecord.setDate(date);
                retailImmunizationSubRecord.setDays((Integer) map.getOrDefault("days", null));
                retailImmunizationSubRecord.setTimes((Integer) map.getOrDefault("times", null));
                retailImmunizationSubRecord.setQuantity((Integer) map.getOrDefault("quantity", null));
                Object dq = map.getOrDefault("drugQuantity",null);
                Double drugQuantity = 0.00;
                if(dq instanceof Integer) drugQuantity = ((Integer)dq).doubleValue();

                if(dq instanceof Float) drugQuantity = ((Float) dq).doubleValue();

                if(dq instanceof Long) drugQuantity = ((Long) dq).doubleValue();

                if(dq == null) drugQuantity = 0.00;

                retailImmunizationSubRecord.setDrugQuantity(drugQuantity);
                retailImmunizationSubRecord.setMethod((Integer) map.getOrDefault("method", null));
                retailImmunizationSubRecord.setDrugUnit((Integer) map.getOrDefault("drugUnit", null));
                retailImmunizationSubRecord.setManufacturerJson((String) map.getOrDefault("manufacturerJson", null));
                retailImmunizationSubRecord.setBatchJson((String) map.getOrDefault("batchJson", null));
                retailImmunizationSubRecord.setOperatorName((String) map.getOrDefault("operatorName", null));
                retailImmunizationSubRecord.setDeleteFlag(DocumentsDeleteFlag.NORMAL.value());

                retailImmunizationSubRecordDao.update(retailImmunizationSubRecord);
            }
        }
    }
}
